using System;
using System.Collections;
using System.Collections.Generic;
using Cinemachine;
using DG.Tweening;
using UnityEngine;
using UnityEngine.AI;

public class PlayerController : MonoBehaviour
{
    private CharacterStats characterStats;
    private Animator anim;
    private NavMeshAgent agent;
    private float stopDistance;
    public Camera FloowedCamera;



    private List<GameObject> attackTargets = new List<GameObject>();
    private float lastAttackTime;
    public AudioSource AudioSource;
    public AudioClip attackAudio;

    private bool stopAudio;

    bool isDeath;
    public bool Rolling;

    

    private void JudgeAttackTargets()
    {
        foreach (var attackTarget in attackTargets)
        {
            if (attackTarget == null)
            {
                attackTargets.Remove(attackTarget);
                break;
            }

            if (Vector3.Distance(transform.position, attackTarget.transform.position) <
                characterStats.attackData.attackRange && transform.IsFacingTarget(attackTarget.transform))
            {
                attackTargets.Remove(attackTarget);
                break;
            }
                
                
        }
    }
    // Start is called before the first frame update
    public virtual void Awake()
    {
        agent = GetComponent<NavMeshAgent>();
        anim = GetComponent<Animator>();
        characterStats = GetComponent<CharacterStats>();
        stopDistance = agent.stoppingDistance;
        AudioSource = GetComponent<AudioSource>();
        FloowedCamera = Camera.main;
    }

    public virtual void  OnEnable()
    {
        //MouseManager.Instance.OnMouseClicked += MoveToTarget;
        //MouseManager.Instance.OnEnemyAttacked += EventAttack;
        GameManager.Instance.RigisterPlayer(characterStats);

    }

    private void Start()
    {
        //SaveManager.Instance.LoadPlayerData();
    }

    private void OnDisable()
    {
        if (!MouseManager.IsInitialized) return;
        MouseManager.Instance.OnMouseClicked -= MoveToTarget;
        //MouseManager.Instance.OnEnemyAttacked -= EventAttack;
    }

    public virtual void Update()
    {
        if (characterStats.currentHealth == 0)
            isDeath = true;
        if (isDeath)
        {
            GameManager.Instance.NotifyObersever();
        }

        PlayerMove();
        SwitchAnim();
        lastAttackTime -= Time.deltaTime;
        SwitchAdudio();
        EventAttack();
    }

    public void PlayerMove()
    {
        
            agent.isStopped = false;
            Quaternion cameraQuaternion = FloowedCamera.transform.rotation;
            float hMove = Input.GetAxis("Horizontal");
            float vMove = Input.GetAxis("Vertical");

            Vector3 movement = cameraQuaternion * new Vector3(hMove, 0, vMove);
            var mag = movement.magnitude;
            movement.y = 0;
            agent.destination = transform.position + movement.normalized * mag;
            if (!Rolling)
            {
                if (Input.GetKeyDown(KeyCode.Space))
                {
                    anim.SetTrigger("Roll");
                    transform.DOMove(transform.position + movement.normalized * 7, 1f);
                }
            }

    }

    public void SwitchAnim()
    {
        anim.SetFloat("Speed", agent.velocity.sqrMagnitude);
        anim.SetBool("Critical", characterStats.isCritical);
        anim.SetBool("Death", isDeath);
    }

    public void MoveToTarget(Vector3 target)
    {
        if (!isDeath)
        {
            StopAllCoroutines();
            agent.stoppingDistance = stopDistance;
            agent.isStopped = false;
            agent.destination = target;
        }
    }

    private void FindAttackTarget()
    {
        GameObject[] Enemys = GameObject.FindGameObjectsWithTag("Enemy");
        foreach (var Enemy in Enemys)
        { 
            if (Vector3.Distance(transform.position, Enemy.transform.position) < characterStats.attackData.attackRange && transform.IsFacingTarget(Enemy.transform))
            {
                attackTargets.Add(Enemy);
            }
        }
    }

    public  void EventAttack()
    {
        if (Input.GetMouseButtonDown(0))
        {
            if (!isDeath)
            {
                JudgeAttackTargets();
                FindAttackTarget();
                if (attackTargets != null)
                {
                    characterStats.isCritical = UnityEngine.Random.value < characterStats.attackData.criticalChance;
                }
                if (lastAttackTime < 0)
                {
                    anim.SetTrigger("Attack");
                    lastAttackTime = characterStats.attackData.coolDown;
                }
            }
        }
    }

    // IEnumerator MoveToAttackTarget()
    // {
    //     if (!isDeath)
    //     {
    //         agent.isStopped = false;
    //         agent.stoppingDistance = characterStats.attackData.attackRange;
    //         transform.LookAt(attackTarget.transform);
    //         while (Vector3.Distance(attackTarget.transform.position, transform.position) > characterStats.attackData.attackRange)
    //         {
    //             agent.destination = attackTarget.transform.position;
    //             yield return null;
    //         }
    //         agent.isStopped = true;
    //
    //         if (lastAttackTime < 0)
    //         {
    //
    //             anim.SetTrigger("Attack");
    //             lastAttackTime = characterStats.attackData.coolDown;
    //         }
    //     }
    // }
    
    

    //Animation Events

    // void Hit()
    // {
    //     if (attackTarget.CompareTag("Attackable"))
    //     {
    //         if (attackTarget.GetComponent<Rock>())
    //         {
    //             attackTarget.GetComponent<Rock>().rockStates = Rock.RockStates.HitEnemy;
    //             attackTarget.GetComponent<Rigidbody>().velocity = Vector3.one;
    //             attackTarget.GetComponent<Rigidbody>().AddForce(transform.forward * 20f, ForceMode.Impulse);
    //         }
    //     }
    //     else
    //     {
    //         var targetStats = attackTarget.GetComponent<CharacterStats>();
    //         targetStats.TakeDamage(characterStats, targetStats);
    //     }
    //
    // }
    
    
    void Hit()
    {
        foreach (var attackTarget in attackTargets)
        {
            if (attackTarget.CompareTag("Enemy"))
            {
                if (attackTarget.GetComponent<Rock>())
                {
                    attackTarget.GetComponent<Rock>().rockStates = Rock.RockStates.HitEnemy;
                    attackTarget.GetComponent<Rigidbody>().velocity = Vector3.one;
                    attackTarget.GetComponent<Rigidbody>().AddForce(transform.forward * 20f, ForceMode.Impulse);
                }
                else
                {
                    var targetStats = attackTarget.GetComponent<CharacterStats>();
                    targetStats.TakeDamage(characterStats, targetStats);
                }
            }
        }
    }

    void AttackAudio()
    {
        AudioSource.PlayClipAtPoint(attackAudio,transform.position);
    }
    
    public void SwitchAdudio()
    {
        if (anim.GetFloat("Speed") <= 0f)
        {
            AudioSource.Pause();
        }
    }

    public void FootAudio()
    {
        AudioSource.Play();
    }
}
